package com.tgy.blog.interceptors;

import com.tgy.constant.RedisKey;
import com.tgy.exception.GlobalException;
import com.tgy.result.GraceJSONResult;
import com.tgy.util.IPUtils;
import com.tgy.util.RedisUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @author tianguiyin
 * @version 1.0
 * @date 2022/8/4 9:59
 * 用于拦截恶意下载和刷评论的
 * 半分钟同一IP只能访问一次
 */
public class CommentFileInterceptor implements HandlerInterceptor {

    @Resource
    public RedisUtils redis;
    @Value("${tgy.commentFileTime}")
    private Long commentFileTime;
    @Value("${tgy.maxCommentFileNumber}")
    private Long maxCommentFileNumber;
    @Value("${tgy.outMaxCommentTime}")
    private Long outMaxCommentTime;

    /**
     * 拦截请求，访问controller之前
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //判断这个IP是否已经被限制访问了
        String userIp = IPUtils.getRequestIp(request);
        userIp = userIp.replaceAll(":",".");
        boolean b = redis.keyIsExist(RedisKey.COMMENT_FILE_VISITS + ":" + userIp);

        // 访问次数限制
        boolean b1 = redis.keyIsExist(RedisKey.COMMENT_FILE_NUMBER + ":" + userIp);
        if (b1){
            int number = Integer.valueOf(redis.get(RedisKey.COMMENT_FILE_NUMBER + ":" + userIp));
            if (number >= maxCommentFileNumber){
                redis.expire(RedisKey.COMMENT_FILE_NUMBER + ":" + userIp,outMaxCommentTime);
                GlobalException.display(GraceJSONResult.error("今日此功能使用次数已达上限！！！"));
                return false;
            }
            redis.increment(RedisKey.COMMENT_FILE_NUMBER + ":" + userIp,1L);
        }else {
            redis.set(RedisKey.COMMENT_FILE_NUMBER + ":" + userIp,"1");
        }

        // 访问时间限制
        if (b){
            GlobalException.display(GraceJSONResult.error("访问过于频繁，请稍后再试"));
            return false;
        }else {
            redis.set(RedisKey.COMMENT_FILE_VISITS + ":" + userIp,userIp,commentFileTime);
        }
        return true;
    }

    /**
     * 请求访问到controller之后，渲染视图之前
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }

    /**
     * 请求访问到controller之后，渲染视图之后
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

    }

}
